package org.vellos.halide.parse;

import java.util.ArrayList;

public class ExpressionTree {

  private ExpressionNode root;

  public ExpressionTree(ExpressionNode root) {
    this.root = root;
  }

  public ExpressionNode getRoot() {
    return root;
  }

  public void replaceLeaf(String value) {
    if(root == getFirstLeaf()) {
      return;
    }

    ArrayList<Object> nodes = getFirstLeaf().getParent().getNodes();
    ExpressionNode leaf = getFirstLeaf();

    for(int i = 0, l = nodes.size(); i < l; i++) {
      if(nodes.get(i) == leaf) {
        nodes.set(i, value);
        return;
      }
    }
  }

  private ExpressionNode getFirstLeafParent(ExpressionNode currentNode, ExpressionNode leaf) {
    for(Object o : currentNode.getNodes()) {
      if(o instanceof ExpressionNode) {
        ExpressionNode node = (ExpressionNode) o;
        if(node == leaf) {
          return currentNode;
        }
      }
    }

    // Current node is not the leaf parent.  Move onto child nodes.

    for(Object o : currentNode.getNodes()) {
      if(o instanceof ExpressionNode) {
        ExpressionNode node = (ExpressionNode) o;
        return getFirstLeafParent(node, leaf);
      }
    }

    return null;
  }

  public ExpressionNode getFirstLeaf() {
    if (root.isLeaf()) {
      return root;
    } else {
      for (Object o : root.getNodes()) {
        if (o instanceof ExpressionNode) {
          return getFirstLeaf((ExpressionNode) o);
        }
      }
    }

    return null;
  }

  private ExpressionNode getFirstLeaf(ExpressionNode expressionNode) {
    if (expressionNode.isLeaf()) {
      return expressionNode;
    } else {
      for (Object o : expressionNode.getNodes()) {
        if (o instanceof ExpressionNode) {
          return getFirstLeaf((ExpressionNode) o);
        }
      }
    }

    return null;
  }
}
